Skip to content

Quarantine unreadable settings instead of wiping them - #405

Merged
btsouth merged 2 commits into
mainfrom
cursor/sbs-1074-settings-read-fail-closed-22d3
Sep 7, 2026
Merged

Quarantine unreadable settings instead of wiping them#405
btsouth merged 2 commits into
mainfrom
cursor/sbs-1074-settings-read-fail-closed-22d3

Conversation

@btsouth

@btsouth btsouth commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Summary

Settings::read_path mapped secure_file::read_string errors (DPAPI unprotect, unsupported ProtectedFile version, IO on an existing file) to defaults with no .bak. The next try_update then atomically replaced the live undecodable settings.json.

Parse failures already quarantine (SBS-954 / SBS-1029). This change treats those read failures the same way:

  • Unlocked load leaves the live file in place and asks load() to retry under the state lock.
  • Locked load / try_update moves the original to settings.json.bak before writing defaults onto the vacated path.

The account ledger persist path had the same fail-open wipe: record_and_persist used load_default() (undecodable → empty) then saved. Persist now fails closed, matching API keys and window_geometry.json.

Related issue

Closes SBS-1074.

Affected areas

  • Tray panel
  • Settings UI
  • Config file / settings persistence
  • CLI
  • Provider-specific behavior
  • Installer / release packaging
  • Startup / background behavior
  • Documentation
  • Other:

Validation

The four new settings tests failed on main before the fix (unlocked read did not set pending_quarantine; try_update wrote defaults over the live file with no .bak). They pass after the change.

Commands run on this Linux cloud agent (Windows-native DPAPI/NTFS not available here):

  • Other:
    • cargo fmt --all --check --manifest-path rust/Cargo.toml — pass
    • cargo test --manifest-path rust/Cargo.toml — pass (1192 lib + 32 bin)
    • cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings — fails on pre-existing Linux-only dead code in secure_file.rs / updater.rs (Windows-gated). Not introduced by this PR. Hosted CI is Windows.
    • cargo test --manifest-path apps/desktop-tauri/src-tauri/Cargo.toml — cannot build here (gdk-3.0 missing). Hosted desktop CI is Windows.

Hosted CI on c0daa54d (rebased onto main / 1.5.36) is green: Frontend, Rust / shared, Rust / desktop, Rust aggregator, and CodeQL all passed. An earlier Rust / shared failure on cli::tty_runner::tests::test_run_sends_script_through_pty was an unrelated PTY flake and did not reproduce.

UI / tray proof

  • Not applicable

Notes for reviewers

  • Settings recovery matches parse failures: quarantine then write defaults to the vacated live path. Readers still fail open.
  • Sibling sweep of secure_file stores:
    • ApiKeys / ManualCookies / token accounts / directory accounts / geometry already fail closed for writers.
    • Account ledger persist now fails closed too. load_default remains fail-open for readers.
  • Derived history stores (usage-history.json, quota-run-history.json, capacity-event baselines) still fail-open then persist. They are rebuildable charts/events, not user-authored settings; left alone to keep this change scoped.
  • Do not merge. Draft PR left open for review.
Open in Web Open in Cursor 

Note

Quarantine unreadable settings and account-ledger files instead of overwriting them

  • Settings loader routes JSON parse, DPAPI, unsupported ProtectedFile version, and IO read failures through Settings::handle_undecodable, which defers quarantine on unlocked reads and moves the file to backup on locked reads. Missing files still initialize defaults.
  • AccountLedger::record_and_persist now uses AccountLedger::persist_if_changed, which strictly loads the existing ledger before saving. Undecodable or unreadable ledgers are left byte-for-byte unchanged; missing ledgers can still be created and persisted.
  • Behavioral Change: Settings::read_path and AccountLedger::persist_if_changed no longer treat unreadable existing files as empty defaults that get overwritten — callers that relied on the old fail-open behavior will see the original corrupt file preserved in the backup path rather than replaced.

Macroscope summarized c0daa54.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 33 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 342956e8-8bec-442b-a05e-c4f477012ecf

📥 Commits

Reviewing files that changed from the base of the PR and between 12b55ce and b29d3ba.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • rust/src/core/account_ledger.rs
  • rust/src/settings.rs
  • rust/src/settings/tests.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ceiling b29d3ba Commit Preview URL

Branch Preview URL
Sep 07 2026, 06:01 PM

Settings::read_path treated DPAPI, unsupported ProtectedFile, and IO
errors as defaults with no .bak, so try_update overwrote the live file.
Match the SBS-954 parse quarantine and fail-closed ledger persist.

Co-authored-by: Tyler <tyler@southboundsoftware.com>
@cursor
cursor Bot force-pushed the cursor/sbs-1074-settings-read-fail-closed-22d3 branch from bd930fc to c0daa54 Compare August 23, 2026 22:30
@btsouth
btsouth marked this pull request as ready for review September 7, 2026 18:00
@btsouth
btsouth merged commit 58520a5 into main Sep 7, 2026
10 of 11 checks passed
@btsouth
btsouth deleted the cursor/sbs-1074-settings-read-fail-closed-22d3 branch September 7, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants